package com.astersoft.lib.cypher;

/*
 * Copyright 2012 AsterSoft personal developer - Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

import java.io.InputStream;
import java.io.OutputStream;

import com.astersoft.lib.cypher.crypt.Encryptable;
import com.astersoft.lib.cypher.crypt.impl.AESEncrypter;
import com.astersoft.lib.cypher.crypt.impl.AESSaltEncrypter;
import com.astersoft.lib.cypher.crypt.impl.DESEncrypter;

/**
 * A generic utility class for encryption stuff
 * 
 * <p>
 * This class is used to encode and decode file or string
 * using a variety of encryption algorithm
 * <p>
 * 
 * @author dario durzo
 * @version 0.1
 * @date 29-05-2012
 */
public class ASCrypt {
	private static final CyAlgorithm DEFAULT_ALGO = CyAlgorithm.DES;
	/**
	 * Enumeration mapper for the
	 * Algorithm implementation
	 * 
	 * @author dario durzo
	 * @version 0.1
	 * @date 29-05-2012
	 */
	public static enum CyAlgorithm {
		DES(new DESEncrypter(), "DJKlkl==Sfs000jsklnds009aAAA"),
		AES(new AESEncrypter(), "WEI99d==33jlkj)DKKdd"),
		AESSALT(new AESSaltEncrypter(), "SOD8sd09j0D980d09j9D09dF09D0");
		
		private CyAlgorithm(Encryptable en, String passPhrase) {
			this._enc = en;
			this._enc.initCypher(passPhrase);
		}
		public void updateKey(String key) {
			this._enc.initCypher(key);
		}
		
		public Encryptable getENC() { return this._enc; }
		private Encryptable _enc;
	}
	
	/**
	 * Encryption functions for text string
	 * 
	 * @param text
	 * @return
	 */
	public static String encrypt(String text) {
		return encrypt(text, DEFAULT_ALGO);
	}
	
	public static String encrypt(String text, String key) {
		return encrypt(text, DEFAULT_ALGO, key);
	}
	
	public static String encrypt(String text, CyAlgorithm alg) {
		return alg.getENC().encrypt(text);
	}
	
	public static String encrypt(String text, CyAlgorithm alg, String key) {
		alg.updateKey(key);
		return encrypt(text, alg);
	}
	
	/**
	 * Encryption functions for input streams
	 * 
	 * @param text
	 * @return
	 */
	public static void encrypt(InputStream in, OutputStream out) {
		encrypt(in, out, DEFAULT_ALGO);
	}
	
	public static void encrypt(InputStream in, OutputStream out, String key) {
		encrypt(in, out, DEFAULT_ALGO, key);
	}
	
	public static void encrypt(InputStream in, OutputStream out, CyAlgorithm alg) {
		alg.getENC().encrypt(in, out);
	}
	
	public static void encrypt(InputStream in, OutputStream out, CyAlgorithm alg, String key) {
		alg.updateKey(key);
		encrypt(in, out, alg);
	}
	
	/**
	 * Decrypt functions for text string
	 * 
	 * @param text
	 * @return
	 */
	public static String decrypt(String text) {
		return decrypt(text, DEFAULT_ALGO);
	}
	
	public static String decrypt(String text, String key) {
		return decrypt(text, DEFAULT_ALGO, key);
	}
	
	public static String decrypt(String text, CyAlgorithm alg) {
		return alg.getENC().decrypt(text);
	}
	
	public static String decrypt(String text, CyAlgorithm alg, String key) {
		alg.updateKey(key);
		return decrypt(text, alg);
	}
	
	/**
	 * Decrypt functions for input streams
	 * 
	 * @param text
	 * @return
	 */
	public static void decrypt(InputStream in, OutputStream out) {
		decrypt(in, out, DEFAULT_ALGO);
	}
	
	public static void decrypt(InputStream in, OutputStream out, String key) {
		decrypt(in, out, DEFAULT_ALGO, key);
	}
	
	public static void decrypt(InputStream in, OutputStream out, CyAlgorithm alg) {
		alg.getENC().decrypt(in, out);
	}
	
	public static void decrypt(InputStream in, OutputStream out, CyAlgorithm alg, String key) {
		alg.updateKey(key);
		decrypt(in, out, alg);
	}
}
